make
基本語法
1 | targets : prerequisites |
範例
範例 1
1 | edit : main.o kbd.o command.o display.o \ |
範例 2 使用變數
1 | #edit : main.o kbd.o command.o display.o \ |
範例 3 隱藏規則(自動推導)
遇到 x.o
會推導出 x.c
為相依,並自動推導出要做 cc -c x.c
1 | # whatever.o |
1 | objects = main.o kbd.o command.o display.o \ |
寫作習慣
- 第一個 label 通常是最終目標 (也是默認目標)
- 最後一個 label 為
clean
- 用
\#
表示#
all
clean
install
print 列出已改文件
tar 打包
dist 壓縮
TAGS 更新所有目標,以备完整地重编译使用
check test 測試 make 流程
Make (尋找 makefile)
GNUmakefile
makefile
Makefile
推薦make -f Make.Linux
ormake --file Make.AIX
引用 makefile
1 | include foo.make a.mk b.mk c.mk e.mk f.mk |
引用 Makefile 尋找位置
-I
or--include-dir
/include (通常是 /usr/local/bin
or/usr/include
)- 環境變數
MAKEFILES
(最好別用,但是出事情最好查一下的地方)
特殊變數
VPATH = src:../headers
, 當文件找不到時去 src, ..headers 尋找MAKECMDGOALS
SHELL
,嵌套执行 make 會自動 exportMAKEFLAGS
,嵌套执行 make 會自動 export,-C -f -h -o -W
參數不會被帶過去
1 | # vpath <pattern> <directories> |
特殊目標
.PHONY
.INTERMEDIATE : mid
中間目標.SECONDARY : sec
不必刪除的中間目標.PRECIOUS
.SUFFIXES: .hack .win
後綴規則(舊規則),.SUFFIXES: # 删除默认的后缀
偽目標 .PHONY
偽目標不需要生成檔案,如 clean
。可以當預設目標,且每次執行一定會執行(不必檢查相依後再產生)
1 | .PHONY : clean |
嵌套执行 make
變數可以透過 make -e out=1
傳入。
或者用 export out = 1
,export
表示全部變數皆傳下去,可以用 unexport out
取消傳入。
也能用 override out = 2
禁止外面傳入
1 | subsystem: |
define
1 | define run-yacc |
變數宣告
=
,有變數中的變數的話,要以各變數的最終值展開:=
,宣告時展開+=
,apped?=
,當變數沒有宣告,才做賦值動作
指令??
@
:不要顯示執行的指令-
:即使執行錯誤也不會中斷
隱規則
中間過程生成物會被 rm -f
方式移除
如 a -> b -> c
,b 會被自動移除
1 | # c |
自動化變數 $@
$<
$@
表示规则中的目标文件集。在模式规则中,如果有多个目标,那么,”$@”就是匹配于
目标中模式定义的集合。
$%
仅当目标是函数库文件中,表示规则中的目标成员名。例如,如果一个目标是”foo.a
(bar.o)”,那么,”$%”就是”bar.o”,”$@”就是”foo.a”。如果目标不是函数库文件(Unix 下是[.a],Windows 下是[.lib]),那么,其值为空。
$<
依赖目标中的第一个目标名字。如果依赖目标是以模式(即”%”)定义的,那么”$<”将
是符合模式的一系列的文件集。注意,其是一个一个取出来的。
$?
所有比目标新的依赖目标的集合。以空格分隔。
$^
所有的依赖目标的集合。以空格分隔。如果在依赖目标中有多个重复的,那个这个变量
会去除重复的依赖目标,只保留一份。
$+
这个变量很像”$^”,也是所有依赖目标的集合。只是它不去除重复的依赖目标。
$
这个变量表示目标模式中”%”及其之前的部分。如果目标是”dir/a.foo.b”,并且目标的
模式是”a.%.b”,那么,”$“的值就是”dir/a.foo”。这个变量对于构造有关联的文件名是比 较有较。如果目标中没有模式的定义,那么”$“也就不能被推导出,但是,如果目标文件的 后缀是 make 所识别的,那么”$“就是除了后缀的那一部分。例如:如果目标是”foo.c”,因 为”.c”是 make 所能识别的后缀名,所以,”$*”的值就是”foo”。这个特性是 GNU make 的
$?
代表已被更新的dependencies的值
也就是dependencies中比target還要新的值
$@
代表target的值
$<
代表第一個dependencies的值
$*
代表target所指定的檔案 不包含副檔名
define run-yacc
yacc $(firstword $^)
mv y.tab.c $@
endef
foo.c : foo.y
$(run-yacc)
$@:$^
“$^”就是“foo.y”
“$@”就是“foo.c”
1 | #<targets ...>: <target-pattern>: <prereq-patterns ...> |
1 | bigoutput littleoutput : text.g |
1 |
|
??
1 | objects = *.o # "*.o" |
p39